// Playwright脚本解析器

/**
 * 解析Playwright脚本并转换为步骤对象
 * @param {string} playwrightScript - Playwright脚本内容
 * @returns {Array} 步骤对象数组
 */
export function parsePlaywrightScript(playwrightScript) {
  const steps = []
  
  if (!playwrightScript || typeof playwrightScript !== 'string') {
    return steps
  }
  
  // 提取测试信息
  const testInfo = extractTestInfo(playwrightScript)
  
  // 分行处理脚本
  const lines = playwrightScript.split('\n')
  let stepIndex = 0
  let currentContext = null // 当前上下文（如：登录流程、搜索流程等）
  let lastNavigationUrl = null // 记录最后一次导航的URL
  let pendingLines = [] // 存储未完成的代码块
  let inMultiLineStatement = false // 标记是否在多行语句中
  
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i]
    const trimmedLine = line.trim()
    const indentLevel = lines[i].search(/\S/) // 获取缩进级别
    
    // 检查是否开始多行语句（不以分号结尾且不是空行或注释）
    if (!trimmedLine.endsWith(';') && trimmedLine && !trimmedLine.startsWith('//') && 
        (trimmedLine.startsWith('await ') || trimmedLine.startsWith('const '))) {
      inMultiLineStatement = true
      pendingLines.push(line)
      continue
    }
    
    // 如果正在收集多行语句
    if (inMultiLineStatement) {
      pendingLines.push(line)
      
      // 如果遇到分号，说明语句结束
      if (trimmedLine.endsWith(';')) {
        inMultiLineStatement = false
        const completeBlock = pendingLines.join('\n')
        pendingLines = []
        
        // 处理完整的代码块
        const step = parseBlockToStep(completeBlock, stepIndex) || parseLineToStep(completeBlock.trim(), stepIndex)
        if (step) {
          if (currentContext) {
            step.context = currentContext
          }
          if (step.type === 'navigation' && step.url) {
            lastNavigationUrl = step.url
            step.isMainNavigation = true
          }
          if (lastNavigationUrl && step.type !== 'navigation') {
            step.pageUrl = lastNavigationUrl
          }
          step.businessMeaning = analyzeBusinessMeaning(step, lines, i)
          step.isCritical = isStepCritical(step)
          step.indentLevel = indentLevel
          steps.push(step)
          stepIndex++
        }
      }
      continue
    }
    
    // 跳过空行、注释和非执行代码（但需要特别处理某些操作）
    if (!trimmedLine || trimmedLine.startsWith('//') || trimmedLine.startsWith('import') || 
        trimmedLine.startsWith('test(') || 
        trimmedLine === '}' || trimmedLine === '});' || trimmedLine === '{') {
      
      // 但是要检查注释中的上下文信息
      if (trimmedLine.startsWith('//')) {
        const contextMatch = trimmedLine.match(/\/\/\s*(?:步骤|Step|Context|流程|Flow)[：:]\s*(.+)/i)
        if (contextMatch) {
          currentContext = contextMatch[1].trim()
        }
      }
      
      continue
    }
    
    // 检查是否是const变量赋值（如 const page1 = await page.waitForEvent('popup')）
    if (trimmedLine.startsWith('const ')) {
      // 处理 waitForEvent 事件等待
      if (trimmedLine.includes('waitForEvent')) {
        const step = parseVariableAssignmentToStep(trimmedLine, stepIndex)
        if (step) {
          if (currentContext) {
            step.context = currentContext
          }
          step.businessMeaning = analyzeBusinessMeaning(step, lines, i)
          step.isCritical = isStepCritical(step)
          step.indentLevel = indentLevel
          steps.push(step)
          stepIndex++
        }
        continue
      }
    }
    
    const step = parseLineToStep(trimmedLine, stepIndex)
    if (step) {
      // 添加上下文信息
      if (currentContext) {
        step.context = currentContext
      }
      
      // 如果是导航步骤，记录URL
      if (step.type === 'navigation' && step.url) {
        lastNavigationUrl = step.url
        step.isMainNavigation = true // 标记为主要导航
      }
      
      // 为其他步骤添加页面信息
      if (lastNavigationUrl && step.type !== 'navigation') {
        step.pageUrl = lastNavigationUrl
      }
      
      // 智能分析步骤的业务含义
      step.businessMeaning = analyzeBusinessMeaning(step, lines, i)
      
      // 检查是否是关键步骤
      step.isCritical = isStepCritical(step)
      
      // 添加缩进级别信息（用于识别嵌套结构）
      step.indentLevel = indentLevel
      
      steps.push(step)
      stepIndex++
    }
  }
  
  // 后处理：分析步骤间的关系
  analyzeStepRelationships(steps)
  
  return steps
}

/**
 * 提取测试信息
 * @param {string} script - 脚本内容
 * @returns {Object} 测试信息对象
 */
function extractTestInfo(script) {
  const testNameMatch = script.match(/test\(['"]([^'"]+)['"],/)
  const describeMatch = script.match(/describe\(['"]([^'"]+)['"],/)
  
  return {
    name: testNameMatch ? testNameMatch[1] : '未命名测试',
    describe: describeMatch ? describeMatch[1] : null
  }
}

/**
 * 将单行代码解析为步骤对象
 * @param {string} line - 代码行
 * @param {number} index - 步骤索引
 * @returns {Object|null} 步骤对象或null
 */
function parseLineToStep(line, index) {
  // 导航操作 - 增强版，支持waitForLoadState检测
  const gotoMatch = line.match(/await\s+page\.goto\s*\(\s*['"]([^'"]+)['"]/)
  if (gotoMatch) {
    // 检查是否有waitForLoadState
    const hasWaitForLoad = line.includes('waitUntil:') || 
                           line.includes('waitForLoadState') || 
                           line.includes('networkidle') ||
                           line.includes('domcontentloaded') ||
                           line.includes('load')
    
    let waitUntilOption = 'load' // 默认值
    const waitUntilMatch = line.match(/waitUntil:\s*['"]([^'"]+)['"]/)
    if (waitUntilMatch) {
      waitUntilOption = waitUntilMatch[1]
    }
    
    return {
      index,
      type: 'navigation',
      name: '打开网页',
      selector: gotoMatch[1],
      url: gotoMatch[1],
      icon: 'fa-globe',
      originalCode: line,
      options: {
        waitForLoadState: hasWaitForLoad,
        waitUntil: waitUntilOption,
        timeout: 30000
      }
    }
  }
  
  // 点击操作 - 支持多种点击方式，包括多行代码和特殊字符
  // 匹配 Playwright 的 getByRole 模式（包含 name 参数）
  const getByRoleMatch1 = line.match(/page\.getByRole\(['"]([^'"]+)['"],\s*{\s*name:\s*['"]([^'"]+)['"]\s*}\)\.click\(\)/)
  if (getByRoleMatch1) {
    const role = getByRoleMatch1[1]
    const name = getByRoleMatch1[2]
    return {
      index,
      type: 'click',
      name: `点击${role}`,
      selector: name,
      clickType: 'click',
      icon: 'fa-mouse-pointer',
      originalCode: line
    }
  }
  
  // 匹配 getByRole 模式（包含 exact 参数）
  const getByRoleMatchExact = line.match(/page\.getByRole\(['"]([^'"]+)['"],\s*{\s*name:\s*['"]([^'"]+)['"],\s*exact:\s*true\s*}\)\.click\(\)/)
  if (getByRoleMatchExact) {
    const role = getByRoleMatchExact[1]
    const name = getByRoleMatchExact[2]
    return {
      index,
      type: 'click',
      name: `点击${role}`,
      selector: name,
      clickType: 'click',
      icon: 'fa-mouse-pointer',
      originalCode: line
    }
  }
  
  // 匹配简化的 getByRole 模式
  const getByRoleMatch2 = line.match(/page\.getByRole\(['"]link['"]\)\.getByText\(['"]((?:[^'"]|'')+)['"]\)/)
  if (getByRoleMatch2) {
    const text = getByRoleMatch2[1]
    return {
      index,
      type: 'click',
      name: '点击链接',
      selector: text,
      clickType: 'click',
      icon: 'fa-mouse-pointer',
      originalCode: line
    }
  }
  
  // 匹配标准的点击操作
  const clickMatch1 = line.match(/await\s+page\.(click|dblclick|tap)\s*\(\s*name=['"]([^'"]+)['"]/)
  const clickMatch2 = line.match(/await\s+page\.(click|dblclick|tap)\s*\(\s*text=['"]([^'"]+)['"]/)
  const clickMatch3 = line.match(/await\s+page\.(click|dblclick|tap)\s*\(\s*['"]([^'"]+)['"]/)
  
  if (clickMatch1 || clickMatch2 || clickMatch3) {
    const clickType = (clickMatch1 || clickMatch2 || clickMatch3)[1]
    let selector = ''
    
    if (clickMatch1) {
      selector = `name="${clickMatch1[2]}"`
    } else if (clickMatch2) {
      selector = `text="${clickMatch2[2]}"`
    } else if (clickMatch3) {
      selector = clickMatch3[2]
    }
    
    return {
      index,
      type: 'click',
      name: getClickActionName(clickType),
      selector: selector,
      clickType,
      icon: 'fa-mouse-pointer',
      originalCode: line
    }
  }
  
  // 输入操作 - 支持fill和type
  const inputMatch = line.match(/await\s+page\.(fill|type)\s*\(\s*['"]([^'"]+)['"],\s*['"]([^'"]*?)['"]/)
  if (inputMatch) {
    const inputType = inputMatch[1]
    const selector = inputMatch[2]
    const value = inputMatch[3]
    
    return {
      index,
      type: 'input',
      name: `输入文本: ${value}`,
      selector,
      value,
      inputType,
      icon: 'fa-keyboard',
      originalCode: line
    }
  }
  
  // 等待事件操作 - waitForEvent
  const waitForEventMatch = line.match(/page\.waitForEvent\(['"]([^'"]+)['"]\)/)
  if (waitForEventMatch) {
    const eventType = waitForEventMatch[1]
    return {
      index,
      type: 'wait',
      name: `等待事件: ${eventType}`,
      selector: eventType,
      icon: 'fa-hourglass-half',
      originalCode: line
    }
  }
  
  
  // 等待超时
  const waitTimeoutMatch = line.match(/await\s+page\.waitForTimeout\s*\(\s*(\d+)\s*\)/)
  if (waitTimeoutMatch) {
    const timeout = parseInt(waitTimeoutMatch[1])
    
    return {
      index,
      type: 'wait',
      name: `等待 ${timeout}ms`,
      timeout,
      icon: 'fa-clock',
      originalCode: line
    }
  }
  
  // 断言操作 - expect
  const expectMatch = line.match(/await\s+expect\s*\(\s*page\.locator\s*\(\s*['"]([^'"]+)['"]\s*\)\s*\)\.(toBeVisible|toHaveText|toContainText|toBeHidden)\s*\(\s*(?:['"]([^'"]*?)['"])?\s*\)/)
  if (expectMatch) {
    const selector = expectMatch[1]
    const assertion = expectMatch[2]
    const expectedValue = expectMatch[3] || ''
    
    return {
      index,
      type: 'assertion',
      name: getAssertionName(assertion, expectedValue),
      selector,
      assertion,
      expectedValue,
      icon: 'fa-check-circle',
      originalCode: line
    }
  }
  
  // 截图操作
  const screenshotMatch = line.match(/await\s+page\.screenshot\s*\(\s*{[^}]*path:\s*['"]([^'"]+)['"]/)
  if (screenshotMatch) {
    const filename = screenshotMatch[1]
    
    return {
      index,
      type: 'screenshot',
      name: `截图: ${filename}`,
      filename,
      icon: 'fa-camera',
      originalCode: line
    }
  }
  
  return null
}

/**
 * 将多行代码块解析为步骤对象
 * @param {string} block - 多行代码块
 * @param {number} index - 步骤索引
 * @returns {Object|null} 步骤对象或null
 */
function parseBlockToStep(block, index) {
  // 尝试解析导航操作
  const gotoMatch = block.match(/await\s+page\.goto\s*\(\s*['"]([^'"]+)['"]/)
  if (gotoMatch) {
    const url = gotoMatch[1]
    const hasWaitForLoad = block.includes('waitUntil:') || 
                           block.includes('waitForLoadState') || 
                           block.includes('networkidle') ||
                           block.includes('domcontentloaded') ||
                           block.includes('load')
    
    let waitUntilOption = 'load'
    const waitUntilMatch = block.match(/waitUntil:\s*['"]([^'"]+)['"]/)
    if (waitUntilMatch) {
      waitUntilOption = waitUntilMatch[1]
    }
    
    return {
      index,
      type: 'navigation',
      name: '打开网页',
      selector: url,
      url: url,
      icon: 'fa-globe',
      originalCode: block,
      options: {
        waitForLoadState: hasWaitForLoad,
        waitUntil: waitUntilOption,
        timeout: 30000
      }
    }
  }
  
  // 尝试解析 getByRole 点击操作（包含 exact 参数）
  const getByRoleMatchExact = block.match(/page\.getByRole\(['"]([^'"]+)['"],\s*{\s*name:\s*['"]([^'"]+)['"],\s*exact:\s*true\s*}\)\.click\(\)/)
  if (getByRoleMatchExact) {
    const role = getByRoleMatchExact[1]
    const name = getByRoleMatchExact[2]
    return {
      index,
      type: 'click',
      name: `点击${role}`,
      selector: name,
      clickType: 'click',
      icon: 'fa-mouse-pointer',
      originalCode: block
    }
  }
  
  // 尝试解析 getByRole 点击操作
  const getByRoleMatch = block.match(/page\.getByRole\(['"]([^'"]+)['"],\s*{\s*name:\s*['"]([^'"]+)['"]\s*}\)\.click\(\)/)
  if (getByRoleMatch) {
    const role = getByRoleMatch[1]
    const name = getByRoleMatch[2]
    return {
      index,
      type: 'click',
      name: `点击${role}`,
      selector: name,
      clickType: 'click',
      icon: 'fa-mouse-pointer',
      originalCode: block
    }
  }
  
  // 尝试解析标准的点击操作
  const clickMatch = block.match(/await\s+page\.(click|dblclick|tap)\s*\(\s*['"]([^'"]+)['"]/)
  if (clickMatch) {
    const clickType = clickMatch[1]
    const selector = clickMatch[2]
    
    return {
      index,
      type: 'click',
      name: getClickActionName(clickType),
      selector,
      clickType,
      icon: 'fa-mouse-pointer',
      originalCode: block
    }
  }
  
  // 尝试解析输入操作
  const inputMatch = block.match(/await\s+page\.(fill|type)\s*\(\s*['"]([^'"]+)['"],\s*['"]([^'"]*?)['"]/)
  if (inputMatch) {
    const inputType = inputMatch[1]
    const selector = inputMatch[2]
    const value = inputMatch[3]
    
    return {
      index,
      type: 'input',
      name: `输入文本: ${value}`,
      selector,
      value,
      inputType,
      icon: 'fa-keyboard',
      originalCode: block
    }
  }
  
  // 尝试解析等待事件操作
  const waitForEventMatch = block.match(/page\.waitForEvent\(['"]([^'"]+)['"]\)/)
  if (waitForEventMatch) {
    const eventType = waitForEventMatch[1]
    return {
      index,
      type: 'wait',
      name: `等待事件: ${eventType}`,
      selector: eventType,
      icon: 'fa-hourglass-half',
      originalCode: block
    }
  }
  
  
  // 尝试解析等待超时
  const waitTimeoutMatch = block.match(/await\s+page\.waitForTimeout\s*\(\s*(\d+)\s*\)/)
  if (waitTimeoutMatch) {
    const timeout = parseInt(waitTimeoutMatch[1])
    
    return {
      index,
      type: 'wait',
      name: `等待 ${timeout}ms`,
      timeout,
      icon: 'fa-clock',
      originalCode: block
    }
  }
  
  // 尝试解析断言操作
  const expectMatch = block.match(/await\s+expect\s*\(\s*page\.locator\s*\(\s*['"]([^'"]+)['"]\s*\)\s*\)\.(toBeVisible|toHaveText|toContainText|toBeHidden)\s*\(\s*(?:['"]([^'"]*?)['"])?\s*\)/)
  if (expectMatch) {
    const selector = expectMatch[1]
    const assertion = expectMatch[2]
    const expectedValue = expectMatch[3] || ''
    
    return {
      index,
      type: 'assertion',
      name: getAssertionName(assertion, expectedValue),
      selector,
      assertion,
      expectedValue,
      icon: 'fa-check-circle',
      originalCode: block
    }
  }
  
  // 尝试解析截图操作
  const screenshotMatch = block.match(/await\s+page\.screenshot\s*\(\s*{[^}]*path:\s*['"]([^'"]+)['"]/)
  if (screenshotMatch) {
    const filename = screenshotMatch[1]
    
    return {
      index,
      type: 'screenshot',
      name: `截图: ${filename}`,
      filename,
      icon: 'fa-camera',
      originalCode: block
    }
  }
  
  return null
}

/**
 * 将变量赋值语句解析为步骤对象
 * @param {string} line - 变量赋值语句
 * @param {number} index - 步骤索引
 * @returns {Object|null} 步骤对象或null
 */
function parseVariableAssignmentToStep(line, index) {
  const match = line.match(/const\s+([a-zA-Z0-9_$]+)\s*=\s*await\s*page\.(waitForEvent|waitForSelector|waitForTimeout)\s*\(\s*['"]([^'"]+)['"]/)
  if (match) {
    const variableName = match[1]
    const eventType = match[2]
    const selector = match[3]
    
    let name = `等待事件: ${eventType}`
    if (eventType === 'waitForEvent') {
      name = `等待事件: ${selector}`
    } else if (eventType === 'waitForSelector') {
      name = `等待元素: ${selector}`
    } else if (eventType === 'waitForTimeout') {
      name = `等待超时: ${selector}`
    }
    
    return {
      index,
      type: 'wait',
      name: name,
      selector: selector,
      icon: 'fa-hourglass-half',
      originalCode: line
    }
  }
  
  return null
}

/**
 * 获取点击动作名称
 * @param {string} clickType - 点击类型
 * @returns {string} 动作名称
 */
function getClickActionName(clickType) {
  const names = {
    'click': '点击元素',
    'dblclick': '双击元素',
    'tap': '轻触元素'
  }
  return names[clickType] || '点击元素'
}

/**
 * 获取断言名称
 * @param {string} assertion - 断言类型
 * @param {string} expectedValue - 期望值
 * @returns {string} 断言名称
 */
function getAssertionName(assertion, expectedValue) {
  const names = {
    'toBeVisible': '验证元素可见',
    'toBeHidden': '验证元素隐藏',
    'toHaveText': `验证文本: ${expectedValue}`,
    'toContainText': `验证包含文本: ${expectedValue}`
  }
  return names[assertion] || '验证断言'
}

/**
 * 分析步骤的业务含义
 * @param {Object} step - 步骤对象
 * @param {Array} lines - 所有代码行
 * @param {number} lineIndex - 当前行索引
 * @returns {string} 业务含义描述
 */
function analyzeBusinessMeaning(step, lines, lineIndex) {
  // 查看前后几行的注释来推断业务含义
  const contextLines = []
  for (let i = Math.max(0, lineIndex - 2); i <= Math.min(lines.length - 1, lineIndex + 2); i++) {
    const line = lines[i].trim()
    if (line.startsWith('//')) {
      contextLines.push(line.substring(2).trim())
    }
  }
  
  if (contextLines.length > 0) {
    return contextLines.join(' ')
  }
  
  // 根据选择器和操作类型推断
  if (step.type === 'input') {
    if (step.selector.includes('username') || step.selector.includes('user')) {
      return '用户名输入'
    }
    if (step.selector.includes('password') || step.selector.includes('pwd')) {
      return '密码输入'
    }
    if (step.selector.includes('search') || step.selector.includes('query')) {
      return '搜索输入'
    }
  }
  
  if (step.type === 'click') {
    if (step.selector.includes('login') || step.selector.includes('signin')) {
      return '登录操作'
    }
    if (step.selector.includes('submit') || step.selector.includes('confirm')) {
      return '提交操作'
    }
    if (step.selector.includes('search')) {
      return '搜索操作'
    }
  }
  
  return ''
}

/**
 * 检查是否是关键步骤
 * @param {Object} step - 步骤对象
 * @returns {boolean} 是否关键
 */
function isStepCritical(step) {
  const criticalKeywords = ['login', 'submit', 'confirm', 'pay', 'order', 'delete']
  const selector = step.selector?.toLowerCase() || ''
  const name = step.name?.toLowerCase() || ''
  
  return criticalKeywords.some(keyword => 
    selector.includes(keyword) || name.includes(keyword)
  )
}

/**
 * 分析步骤间的关系
 * @param {Array} steps - 步骤数组
 */
function analyzeStepRelationships(steps) {
  for (let i = 0; i < steps.length; i++) {
    const step = steps[i]
    const nextStep = steps[i + 1]
    const prevStep = steps[i - 1]
    
    // 分析依赖关系
    if (prevStep) {
      step.dependsOn = prevStep.index
    }
    
    // 分析流程组
    if (step.type === 'navigation') {
      step.flowGroup = 'navigation'
    } else if (step.businessMeaning?.includes('登录') || step.selector?.includes('login')) {
      step.flowGroup = 'login'
    } else if (step.businessMeaning?.includes('搜索') || step.selector?.includes('search')) {
      step.flowGroup = 'search'
    }
  }
}

/**
 * 生成步骤显示信息
 * @param {Object} step - 步骤对象
 * @returns {Object} 显示信息对象
 */
export function generateStepDisplayInfo(step) {
  const displayInfo = {
    name: step.name || '未知步骤',
    icon: step.icon || 'fa-cog',
    selector: step.selector || '',
    detailInfo: [],
    statusInfo: null
  }
  
  // 根据步骤类型生成详细信息
  switch (step.type) {
    case 'navigation':
      displayInfo.detailInfo.push({
        label: 'URL',
        value: step.url || step.selector
      })
      break
      
    case 'input':
      displayInfo.detailInfo.push({
        label: '输入值',
        value: step.value || ''
      })
      break
      
    case 'wait':
      if (step.timeout) {
        displayInfo.detailInfo.push({
          label: '等待时间',
          value: `${step.timeout}ms`
        })
      }
      break
      
    case 'assertion':
      displayInfo.detailInfo.push({
        label: '断言类型',
        value: step.assertion || ''
      })
      if (step.expectedValue) {
        displayInfo.detailInfo.push({
          label: '期望值',
          value: step.expectedValue
        })
      }
      break
  }
  
  return displayInfo
}

/**
 * 获取步骤图标
 * @param {Object} step - 步骤对象
 * @returns {string} 图标类名
 */
export function getStepIcon(step) {
  const iconMap = {
    'navigation': 'fa-globe',
    'click': 'fa-mouse-pointer',
    'input': 'fa-keyboard',
    'wait': 'fa-hourglass-half',
    'assertion': 'fa-check-circle',
    'screenshot': 'fa-camera'
  }
  
  return iconMap[step.type] || 'fa-cog'
}

/**
 * 替换预设步骤为解析后的步骤
 * @param {Array} parsedSteps - 解析后的步骤数组
 */
export function replacePresetStepsWithParsed(parsedSteps) {
  // 这个函数在Vue版本中会通过store来处理
  // 这里提供接口保持兼容性
  console.log('替换步骤为解析后的步骤:', parsedSteps.length, '个步骤')
  
  // 触发自定义事件，让Vue组件监听
  if (typeof window !== 'undefined') {
    window.dispatchEvent(new CustomEvent('stepsReplaced', {
      detail: { steps: parsedSteps }
    }))
  }
}